#include"mystdio.h"
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>

MyFILE* my_fopen(const char * filename, const char* mode)
{
  int fd = -1;
  if(strcmp(mode, "w") == 0)
  {//@1如果指定文件不存在，就创建文件
  //@2进程后续只能对该文件执行写入操作，无法读取文件内容 
  //@3清空文件原有内容 
    fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, UMASK);
  }
  else if(strcmp(mode, "r") == 0)
  {
    //@1以只读模式打开文件
    fd = open(filename, O_RDONLY);
  }
  else if(strcmp(mode, "a") == 0)
  {
    //@3用于指定以追加模式打开文件
    fd = open(filename, O_CREAT | O_WRONLY | O_APPEND, UMASK);
  }
  else if(strcmp(mode, "a+") == 0)
  {
    //@2程序既能够从文件里读取数据，也可以往文件中写入数据
    fd = open(filename, O_CREAT | O_RDWR | O_APPEND, UMASK);
  }
  else
  {}

  if(fd < 0)
    return NULL;

  MyFILE* fp = (MyFILE*)malloc(sizeof(MyFILE));
  if(!fp)
    return NULL;

  fp->fileno = fd;
  fp->flag = FLUSH_LINE;
  fp->curr = 0;
  fp->cap = SIZE;
  fp->outbuffer[0] = 0;

  return fp;
}

static void my_fflush_core(MyFILE* fp, int force)
{
  if(fp->curr <= 0)
    return;
  if(force == FORCE)
  {
    write(fp->fileno, fp->outbuffer, fp->curr);
    fp->curr = 0;
  }
  else
  {
    //开始刷新，必须符合刷新条件
    if((fp->flag & FLUSH_LINE) && fp->outbuffer[fp->curr-1] == '\n')
    {
      //开始刷新,write()本质是拷贝
      write(fp->fileno, fp->outbuffer, fp->curr);
      fp->curr = 0;
    }
    else if((fp->fileno & FLUSH_FULL) && fp->curr == fp->cap)
    {
      write(fp->fileno, fp->outbuffer, fp->curr);
      fp->curr = 0;
    }
    else 
    {

    }
  }
}

//void my_fclose(MyFILE *fp);
int my_fwrite(const char* s, int size, MyFILE* fp)
{
  //考虑fwrite的本质？
  memcpy(fp->outbuffer+fp->curr, s, size);//fwrite完成
  fp->curr += size;
  my_fflush_core(fp, NORMAL);
  return size;
}

void my_fflush(MyFILE* fp)
{
  my_fflush_core(fp, FORCE);
}

void my_fclose(MyFILE* fp)
{
  if(fp->fileno >= 0)
  {
    my_fflush(fp);// 用户-》C
    fsync(fp->fileno);// C-》内核
    close(fp->fileno);
    free(fp);
  }
}
